package com.atguigu.gulimall.product.service.impl;

import com.atguigu.gulimall.product.dao.PmsAttrAttrgroupRelationDao;
import com.atguigu.gulimall.product.dao.PmsAttrGroupDao;
import com.atguigu.gulimall.product.entity.PmsAttrAttrgroupRelationEntity;
import com.atguigu.gulimall.product.entity.PmsAttrGroupEntity;
import com.atguigu.gulimall.product.entity.PmsCategoryEntity;
import com.atguigu.gulimall.product.service.PmsAttrGroupService;
import com.atguigu.gulimall.product.service.PmsCategoryService;
import com.atguigu.gulimall.product.vo.PmsAttrVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.PmsAttrDao;
import com.atguigu.gulimall.product.entity.PmsAttrEntity;
import com.atguigu.gulimall.product.service.PmsAttrService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("pmsAttrService")
public class PmsAttrServiceImpl extends ServiceImpl<PmsAttrDao, PmsAttrEntity> implements PmsAttrService {
    @Resource
    private PmsAttrAttrgroupRelationServiceImpl attrAttrgroupRelationService;
    @Resource
    private PmsAttrGroupService pmsAttrGroupService;
    @Resource
    private PmsCategoryService pmsCategoryService;
    @Resource
    private PmsAttrAttrgroupRelationDao relationDao;
    @Resource
    private PmsAttrGroupDao attrGroupDao;
    @Resource
    private PmsAttrDao attrDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PmsAttrEntity> page = this.page(
                new Query<PmsAttrEntity>().getPage(params),
                new QueryWrapper<PmsAttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils getListByCatelogId(String type,Long catelogId, Map<String, Object> params) {
        QueryWrapper<PmsAttrEntity> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("catelog_id",catelogId);
        if(type.equalsIgnoreCase("base")){
            queryWrapper.eq("attr_type",1);
        }else{
            queryWrapper.eq("attr_type",0);
        }

        String key=(String) params.get("key");
        if(StringUtils.isNotBlank(key)){
            queryWrapper.eq("attr_name",key);
        }
        List<PmsAttrVo> pmsAttrVos=new ArrayList<>();
        IPage<PmsAttrEntity> page = this.page(new Query<PmsAttrEntity>().getPage(params), queryWrapper);
        PageUtils pageUtils=new PageUtils(page);
        List<PmsAttrEntity> records = page.getRecords();
        for (PmsAttrEntity pmsAttrEntity:records) {
            PmsAttrVo pmsAttrVo= new PmsAttrVo();
            BeanUtils.copyProperties(pmsAttrEntity,pmsAttrVo);
            QueryWrapper<PmsAttrAttrgroupRelationEntity> attrGroupWapper=new QueryWrapper<>();
            attrGroupWapper.eq("attr_id",pmsAttrEntity.getAttrId());
            PmsAttrAttrgroupRelationEntity one = attrAttrgroupRelationService.getOne(attrGroupWapper);
            if(one!=null){
                PmsAttrGroupEntity byId = pmsAttrGroupService.getById(one.getAttrGroupId());
                pmsAttrVo.setGroupName(byId.getAttrGroupName());
            }
            PmsCategoryEntity byId1 = pmsCategoryService.getById(pmsAttrEntity.getCatelogId());
            pmsAttrVo.setCatelogName(byId1.getName());
            pmsAttrVos.add(pmsAttrVo);
        }
        pageUtils.setList(pmsAttrVos);
        return pageUtils;
    }

    @Override
    public PmsAttrVo getDataById(Long attrId) {
        PmsAttrEntity pmsAttr = this.getById(attrId);
        PmsAttrVo pmsAttrVo=new PmsAttrVo();
        BeanUtils.copyProperties(pmsAttr,pmsAttrVo);
        List<Long> catelogPath=new LinkedList<>();
        this.getCatelogPath(catelogPath,pmsAttr.getCatelogId());
        Collections.reverse(catelogPath);
        pmsAttrVo.setCatelogPath(catelogPath);
        QueryWrapper<PmsAttrAttrgroupRelationEntity> attrGroupWapper=new QueryWrapper<>();
        attrGroupWapper.eq("attr_id",attrId);
        PmsAttrAttrgroupRelationEntity one = attrAttrgroupRelationService.getOne(attrGroupWapper);
        if(one!=null) pmsAttrVo.setAttrGroupId(one.getAttrGroupId());
        return pmsAttrVo;
    }

    @Override
    @Transactional
    public void saveAttr(PmsAttrVo pmsAttrVo) {
        PmsAttrEntity pmsAttr=new PmsAttrEntity();
        BeanUtils.copyProperties(pmsAttrVo,pmsAttr);
        this.save(pmsAttr);
        if(pmsAttrVo.getAttrType()==1){
            PmsAttrAttrgroupRelationEntity attrAttrgroupRelationEntity=new PmsAttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrGroupId(pmsAttrVo.getAttrGroupId());
            attrAttrgroupRelationEntity.setAttrId(pmsAttr.getAttrId());
            attrAttrgroupRelationEntity.setAttrSort(0);
            //保存中间表数据
            attrAttrgroupRelationService.save(attrAttrgroupRelationEntity);
        }
    }

    @Override
    @Transactional
    public void deleteByIds(List<Long> asList) {
        this.removeByIds(asList);
        for (Long attrId:asList) {
             QueryWrapper<PmsAttrAttrgroupRelationEntity> queryWrapper=new QueryWrapper<>();
             queryWrapper.eq("attr_id",attrId);
            attrAttrgroupRelationService.remove(queryWrapper);
        }
    }

    public void getCatelogPath(List<Long> catelogPath,Long catelogId) {
        catelogPath.add(catelogId);
        PmsCategoryEntity byId = pmsCategoryService.getById(catelogId);
        if(byId.getParentCid()!=0){
            this.getCatelogPath(catelogPath,byId.getParentCid());
        }

    }

    /**
     * 根据分组id查找关联属性
     */
    @Override
    public List<PmsAttrEntity> getRelationAttr(Long attrgroupId) {
        List<PmsAttrAttrgroupRelationEntity> entities = relationDao.selectList(new QueryWrapper<PmsAttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId));
        List<Long> attrIds = entities.stream().map((attr) -> attr.getAttrId()).collect(Collectors.toList());
        // 根据这个属性查询到的id可能是空的
        if(attrIds == null || attrIds.size() == 0){
            return null;
        }
        return this.listByIds(attrIds);
    }

    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
        //1、当前分组只能关联自己所属的分类里面的所有属性
        PmsAttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();
        // 2、当前分组只能别的分组没有引用的属性																									并且这个分组的id不是我当前正在查的id
        //2.1)、当前分类下的其他分组
        List<PmsAttrGroupEntity> group = attrGroupDao.selectList(new QueryWrapper<PmsAttrGroupEntity>().eq("catelog_id", catelogId));
        // 得到当前分类下面的所有分组id
        List<Long> collect = group.stream().map(item -> {
            return item.getAttrGroupId();
        }).collect(Collectors.toList());

        //2.2)、查询这些分组关联的属性
        List<PmsAttrAttrgroupRelationEntity> groupId = relationDao.selectList(new QueryWrapper<PmsAttrAttrgroupRelationEntity>().in("attr_group_id", collect));
        // 再次获取跟这些分组有关的属性id的集合
        List<Long> attrIds = groupId.stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        //2.3)、从当前分类的所有属性中移除这些属性；[因这些分组已经存在被选了 就不用再显示了]
        QueryWrapper<PmsAttrEntity> wrapper = new QueryWrapper<PmsAttrEntity>().eq("catelog_id", catelogId).eq("attr_type", 1);
        if(attrIds != null && attrIds.size() > 0){
            wrapper.notIn("attr_id", attrIds);
        }
        // 当搜索框中有key并且不为空的时候 进行模糊查询
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            wrapper.and((w)->{
                w.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        // 将最后返回的结果进行封装
        IPage<PmsAttrEntity> page = this.page(new Query<PmsAttrEntity>().getPage(params), wrapper);

        PageUtils pageUtils = new PageUtils(page);
        return pageUtils;
    }

    @Override
    public List<Long> selectSearchAttrIds(List<Long> attrIds) {
        return attrDao.selectSearchAttrIds(attrIds);
    }

}